<script setup lang="ts">
import {createTable} from '@/api/tool/gen';

const {proxy} = getCurrentInstance() as ComponentInternalInstance;

const emit = defineEmits(['ok']);

// 遮罩层
const visible = ref(false);

// 表配置
const tableConfig = reactive({
  name: '',
  engine: 'InnoDB',
  autoIncrementStep: 1,
  comment: ''
});

// 字段配置
const fields = ref([
  {
    name: 'id',
    type: 'bigint',
    isNotNull: true,
    isAutoIncrement: true,
    isPrimary: true,
    comment: '主键',
    defaultValue: '' // 添加默认值属性
  },
  {
    name: 'create_by',
    type: 'varchar(64)',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '创建者',
    defaultValue: '\'\'' // 添加默认值属性
  },
  {
    name: 'create_time',
    type: 'datetime',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '创建时间',
    defaultValue: '' // 添加默认值属性
  },
  {
    name: 'update_by',
    type: 'varchar(64)',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '更新者',
    defaultValue: '\'\'' // 添加默认值属性
  },
  {
    name: 'update_time',
    type: 'datetime',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '更新时间',
    defaultValue: '' // 添加默认值属性
  },
  {
    name: 'remark',
    type: 'varchar(500)',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '备注',
    defaultValue: 'null' // 添加默认值属性
  },
  {
    name: '',
    type: '',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '',
    defaultValue: 'null' // 添加默认值属性
  }
]);

// 动态添加字段
const addField = () => {
  fields.value.push({
    name: '',
    type: '',
    isNotNull: false,
    isAutoIncrement: false,
    isPrimary: false,
    comment: '',
    defaultValue: 'null' // 添加默认值属性
  });
};

//标签切换清空sql
const handleTabClick = (tab, event) => {
  sqlLanguage.value = '';
};

// 移除字段
const removeField = (index: number) => {
  fields.value.splice(index, 1);
};

const createSQL = () => {
  if (!tableConfig.name) {
    //throw new Error("数据表名不能为空");
    return;
  }
  let sql = `CREATE TABLE \`${tableConfig.name}\` (\n`;
  let primaryKey = '';
  fields.value.forEach((field, i) => {
    // 添加字段名称和类型
    sql += `  \`${field.name}\` ${field.type}`;
    // 添加 NOT NULL
    if (field.isNotNull) {
      sql += ' NOT NULL';
    }
    // 添加 AUTO_INCREMENT
    if (field.isAutoIncrement) {
      sql += ' AUTO_INCREMENT';
    }
    // 添加 DEFAULT 值
    if (field.defaultValue !== null && field.defaultValue !== undefined) {
      if (field.defaultValue === 'NULL') {
        sql += ' DEFAULT NULL';
      } else if (typeof field.defaultValue === 'number' || !isNaN(Number(field.defaultValue))) { // 数字
        sql += ` DEFAULT ${field.defaultValue}`;
      } else { // 字符串
        sql += ` DEFAULT '${field.defaultValue}'`;
      }
    }
    // 添加 PRIMARY KEY
    if (field.isPrimary) {
      sql += ' PRIMARY KEY';
      if (primaryKey) {
        return;
        //throw new Error("多个主键定义，请检查字段配置");
      }
      primaryKey = field.name;
    }
    // 添加注释
    if (field.comment) {
      sql += ` COMMENT '${field.comment}'`;
    }
    // 添加逗号（除了最后一个字段）
    sql += i < fields.value.length - 1 ? ',\n' : '\n';
  });
  if (!primaryKey && fields.value.some((field) => field.isPrimary)) {
    return;
    //throw new Error("多个主键定义，请检查字段配置");
  }
  // 添加表引擎、自增步长和表注释
  sql += `) ENGINE=${tableConfig.engine} AUTO_INCREMENT=${tableConfig.autoIncrementStep + 1} COMMENT='${tableConfig.comment}';`;
  return sql;
}

const sqlLanguage = ref('');

const sqlVisualization = computed(() => {
  try {
    return createSQL();
  } catch (error: any) {
    return error.message;
  }
});

/** 创建按钮操作 */
const handleCreateTable = () => {
  console.log(sqlLanguage.value);
  if (sqlLanguage.value !== '') {
    console.log(sqlLanguage.value);
    const sql = sqlLanguage.value;
    createTable({sql}).then((res) => {
      proxy?.modal.msgSuccess(res.msg);
      if (res.code === 200) {
        visible.value = false;
        emit('ok');
      }
    });
  } else {
    console.log(sqlVisualization);
    const sql = sqlVisualization;
    createTable({sql}).then((res) => {
      proxy?.modal.msgSuccess(res.msg);
      if (res.code === 200) {
        visible.value = false;
        emit('ok');
      }
    });
  }
};

// 显示弹框
const show = () => {
  visible.value = true;
};

defineExpose({show});

//自动补全输入框
interface RestaurantItem {
  value: string;
}

const state1 = ref('');

const restaurants = ref<RestaurantItem[]>([]);
const querySearch = (queryString: string, cb: any) => {
  const results = queryString
      ? restaurants.value.filter(createFilter(queryString))
      : restaurants.value;
  // call callback function to return suggestions
  cb(results);
};
const createFilter = (queryString: string) => {
  return (restaurant: RestaurantItem) => {
    return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0;
  };
};
const loadAll = () => {
  return [
    {value: 'bigint'},
    {value: 'binary'},
    {value: 'bit'},
    {value: 'blob'},
    {value: 'boolean'},
    {value: 'char'},
    {value: 'date'},
    {value: 'datetime'},
    {value: 'decimal'},
    {value: 'double'},
    {value: 'enum'},
    {value: 'float'},
    {value: 'geometry'},
    {value: 'geography'},
    {value: 'geometrycollection'},
    {value: 'int'},
    {value: 'integer'} /* int与integer可以视为相同 */,
    {value: 'json'},
    {value: 'longblob'},
    {value: 'longtext'},
    {value: 'linestring'},
    {value: 'mediumblob'},
    {value: 'mediumint'},
    {value: 'mediumtext'},
    {value: 'multilinestring'},
    {value: 'multipolygon'},
    {value: 'nchar'},
    {value: 'numeric'},
    {value: 'nvarchar'},
    {value: 'point'},
    {value: 'polygon'},
    {value: 'real'},
    {value: 'set'},
    {value: 'smallint'},
    {value: 'text'},
    {value: 'time'},
    {value: 'timestamp'},
    {value: 'tinyblob'},
    {value: 'tinyint'},
    {value: 'tinytext'},
    {value: 'varbinary'},
    {value: 'varchar'},
    {value: 'year'}
  ];
};

const handleSelect = (item: RestaurantItem) => {
  console.log(item);
};

// 识别Sql语句
const recognitionSql = ref('');

// 定义字段配置类型
type FieldTime = {
  name: string;
  type: string;
  isNotNull: boolean;
  isAutoIncrement: boolean;
  isPrimary: boolean;
  comment: string;
  defaultValue: string | null;
};

// 定义表配置类型
type TableTime = {
  name: string;
  engine: string;
  autoIncrementStep: number;
  comment: string;
};

const recognition = () => {
  console.log(recognitionSql.value);
  fields.value = parseSqlToConfig(recognitionSql.value).fields as any;
  const tableTime = parseSqlToConfig(recognitionSql.value).tableConfig;
  tableConfig.autoIncrementStep = tableTime.autoIncrementStep;
  tableConfig.comment = tableTime.comment;
  tableConfig.engine = tableTime.engine;
  tableConfig.name = tableTime.name;
};

const parseSqlToConfig = (sql: string): { tableConfig: TableTime; fields: FieldTime[] } => {
  // 解析表名
  const createTableIndex = sql.toUpperCase().indexOf('CREATE TABLE');
  if (createTableIndex === -1) {
    throw new Error('Invalid SQL: CREATE TABLE statement not found.');
  }

  const openParenthesisIndex = sql.indexOf('(', createTableIndex);
  if (openParenthesisIndex === -1) {
    throw new Error('Invalid SQL: Opening parenthesis not found after CREATE TABLE.');
  }

  let tableName = sql.substring(createTableIndex + 'CREATE TABLE'.length, openParenthesisIndex).trim();
  tableName = tableName.replace(/`/g, ''); // 去掉反引号

  // 解析引擎
  const engineRegex = /ENGINE\s*=\s*(\w+)/i;
  const engineMatch = sql.match(engineRegex);
  const engine = engineMatch ? engineMatch[1] : 'InnoDB';

  // 解析自增步长
  const autoIncrementRegex = /AUTO_INCREMENT\s*=\s*(\d+)/i;
  const autoIncrementMatch = sql.match(autoIncrementRegex);
  const autoIncrementStep = autoIncrementMatch ? parseInt(autoIncrementMatch[1], 10) : 1;

  // 解析表注释
  const tableCommentRegex = /COMMENT\s*=\s*'([^']+)'/i;
  const tableCommentMatch = sql.match(tableCommentRegex);
  const tableComment = tableCommentMatch ? tableCommentMatch[1] : '';

  // 提取字段定义部分
  const fieldDefinitionStart = openParenthesisIndex + 1;
  const fieldDefinitionEnd = sql.lastIndexOf(')');
  const fieldDefinition = sql.substring(fieldDefinitionStart, fieldDefinitionEnd).trim();

  // 分离字段定义和主键定义
  const lines = fieldDefinition.split(',').map(line => line.trim());
  const fields: FieldTime[] = [];
  let primaryKey: string | null = null;

  for (const line of lines) {
    if (line.toUpperCase().startsWith('PRIMARY KEY')) {
      const primaryKeyRegex = /PRIMARY KEY $(`?[\w, ]+`?)$/i;
      const primaryKeyMatch = line.match(primaryKeyRegex);
      if (primaryKeyMatch && primaryKeyMatch[1]) {
        primaryKey = primaryKeyMatch[1].replace(/`/g, '').trim();
      }
      continue;
    }

    const parts = line.split(/\s+/).filter(part => part);

    if (parts.length < 2) continue; // 跳过无效行

    const name = parts[0].replace(/`/g, '');
    const type = parts[1];
    const isNotNull = parts.some(part => part.toUpperCase() === 'NOT NULL');
    const isAutoIncrement = parts.some(part => part.toUpperCase() === 'AUTO_INCREMENT');

    // 处理默认值
    let defaultValue: string | null = null;
    const defaultValueIndex = parts.findIndex(part => part.toUpperCase() === 'DEFAULT');
    if (defaultValueIndex !== -1 && defaultValueIndex < parts.length - 1) {
      // 默认值可能包含空格或特殊字符，需要从当前索引开始到下一个关键字前的所有部分
      const remainingParts = parts.slice(defaultValueIndex + 1);
      let value = '';
      for (const part of remainingParts) {
        if (['NOT', 'NULL', 'COMMENT'].includes(part.toUpperCase())) {
          break;
        }
        value += part + ' ';
      }
      defaultValue = value.trim();
    }

    // 处理注释
    let comment = '';
    const commentIndex = parts.findIndex(part => part.toUpperCase() === 'COMMENT');
    if (commentIndex !== -1 && commentIndex < parts.length - 1) {
      comment = parts.slice(commentIndex + 1).join(' ').replace(/'/g, '').trim();
    }

    fields.push({
      name,
      type,
      isNotNull,
      isAutoIncrement,
      isPrimary: false, // 主键信息需额外处理
      comment,
      defaultValue
    });
  }

  // 处理主键信息
  if (primaryKey) {
    const primaryKeys = primaryKey.split(',').map(key => key.trim());
    for (const primaryKey of primaryKeys) {
      const fieldToUpdate = fields.find(field => field.name === primaryKey);
      if (fieldToUpdate) {
        fieldToUpdate.isPrimary = true;
      }
    }
  }

  // 返回表配置和字段配置
  return {
    tableConfig: {
      name: tableName,
      engine,
      autoIncrementStep,
      comment: tableComment
    },
    fields
  };
}

onMounted(() => {
  restaurants.value = loadAll();
});
</script>

<template>
  <!-- 创建表 -->
  <el-dialog title="创建表" v-model="visible" width="1200px" top="5vh" append-to-body>
    <el-tabs type="border-card" @tab-click="handleTabClick">
      <el-tab-pane label="SQL语句创建">
        <CodeEditor v-model:text-value="sqlLanguage" :placeholder="'请输入SQL语句'" :tab-boolean="false"
                    :dark-boolean="true"
                    :language="'sql'"></CodeEditor>
      </el-tab-pane>
      <el-tab-pane label="可视化创建">
        <el-form label-width="120px">
          <el-row>
            <el-col :span="8">
              <el-form-item label="数据表名">
                <el-input v-model="tableConfig.name" placeholder="请输入数据表名"></el-input>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="驱动类型">
                <el-select v-model="tableConfig.engine" placeholder="请选择驱动类型">
                  <el-option label="InnoDB" value="InnoDB"></el-option>
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="自增增量">
                <el-input-number v-model="tableConfig.autoIncrementStep" label="自增增量"></el-input-number>
              </el-form-item>
            </el-col>
          </el-row>
          <el-form-item label="数据表备注">
            <el-input v-model="tableConfig.comment" placeholder="请输入数据表备注"></el-input>
          </el-form-item>
          <el-form-item label="SQL语句识别">
            <CodeEditor v-model:text-value="recognitionSql" :placeholder="'请输入SQL语句'" :tab-boolean="false"
                        :dark-boolean="true"
                        :language="'sql'"></CodeEditor>
            <el-button @click="recognition" type="primary">识别</el-button>
          </el-form-item>
          <el-form-item label="字段配置">
            <el-button type="text" @click="addField">添加字段</el-button>
            <el-table :data="fields" style="width: 100%" border>
              <el-table-column prop="name" label="字段名">
                <template #default="{ row, $index }">
                  <el-input v-model="row.name" placeholder="请输入字段名"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="type" label="字段类型">
                <template #default="{ row, $index }">
                  <el-autocomplete v-model="row.type" :fetch-suggestions="querySearch" clearable
                                   class="inline-input w-50" placeholder="请输入字段类型" @select="handleSelect"/>
                </template>
              </el-table-column>
              <el-table-column prop="isNotNull" label="是否非空" width="80">
                <template #default="{ row, $index }">
                  <el-checkbox v-model="row.isNotNull"/>
                </template>
              </el-table-column>
              <el-table-column prop="isAutoIncrement" label="是否自增" width="80">
                <template #default="{ row, $index }">
                  <el-checkbox v-model="row.isAutoIncrement"/>
                </template>
              </el-table-column>
              <el-table-column prop="isPrimary" label="是否主键" width="80">
                <template #default="{ row, $index }">
                  <el-checkbox v-model="row.isPrimary"/>
                </template>
              </el-table-column>
              <el-table-column prop="comment" label="字段备注">
                <template #default="{ row, $index }">
                  <el-input v-model="row.comment" placeholder="请输入字段备注"></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="defaultValue" label="默认值">
                <template #default="{ row, $index }">
                  <el-input v-model="row.defaultValue" placeholder="请输入默认值"></el-input>
                </template>
              </el-table-column>
              <el-table-column fixed="right" label="操作" width="100">
                <template #default="{ row, $index }">
                  <el-button type="text" @click="removeField($index)">移除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-form-item>
          <el-form-item>
            <el-input v-model="sqlVisualization" type="textarea" :rows="20" disabled/>
          </el-form-item>
        </el-form>
      </el-tab-pane>
    </el-tabs>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="visible = false">取 消</el-button>
        <el-button type="primary" @click="handleCreateTable">确 定</el-button>
      </span>
    </template>
  </el-dialog>
</template>
